"""
类方法
    类方法在类中通过 @classmethod 定义，第一个参数为cls，代表类本身。
    类方法可以被类和实例对象调用。
    可以访问类属性。
    在不创建实例的情况下调用，通过类名直接调用，非常方便，适合一些和类整体相关的操作。
静态方法
    静态方法在类中通过 @staticmethod 定义
    不访问实例属性或类属性，只依赖于传入的参数
    可以通过类名或实例调用，但它不会访问类或实例的内部信息，更像是一个工具函数，只是为了方便组织代码，把它放在了类里面。
"""

# ##### 定义一个类
class Player(object):
    # 类的属性（类似java中的静态属性）
    invokedCnt = 0

    # 定义初始化函数（类似java中的构造函数,self类似this）
    def __init__(self, name, age):
        # 此处的 name 和 age 是实例属性
        self.name = name
        # 调用静态方法
        Player.check_age(age)
        self.age = age
        Player.invokedCnt = Player.invokedCnt + 1

    # 创建实例方法
    def showinfo(self):
        print("\n我当前是第%d个玩家" % Player.invokedCnt)
        print("我的基本信息如下", self.__dict__)

    # 创建类方法（类似java中的静态方法）
    @classmethod
    def showinvokedcnt(cls):
        return cls.invokedCnt

    # 静态方法 （静态方法及不与实例绑定也不与类绑定，它只是一个普通的方法）
    @staticmethod
    def check_age(age):
        if age < 18:
            raise Exception("您的年龄过小")


# ##### 创建一个对象
tom = Player(name="Tom", age=18)
# ##### 如果city 这个属性是 tom 这个实例独有的， 那么可以这样增加一个实例属性
tom.city = "武汉"
print("name=", tom.name, "age=", tom.age, "city=", tom.city)
print("类的属性", Player.invokedCnt)

# ##### 获取一个对象的所有属性和值
print("获取一个对象的所有属性和值", tom.__dict__, type(tom.__dict__))

# ##### 调用实例方法
tom.showinfo()

# ##### 调用类方法
print("调用类方法", Player.showinvokedcnt());
